/*
/myclient
*/

#include "terminalHandler.h"
#include "connection.h"
#include "messagehandler.h"
#include "protocol.h"

using namespace std;
using namespace terminal;
using namespace client_server;
using namespace protocol;	


void run (Connection* conn) {
	MessageHandler parser;
	
	terminalHandler* t = new terminalHandler();

	string message;
	int newsGroupId;
	int articleId;
	string author;
	string name;
	string text;
	int toAddIfExecuted;
	
	while(true) {
		
		stringstream ss;
		container newtuple = t->read();		

		//Loads the information about what is to be done into theese variables.
		message = get<0>(newtuple);
		newsGroupId = get<1>(newtuple);
		articleId = get<2>(newtuple);
		author = get<3>(newtuple);
		name = get<4>(newtuple);
		text = get<5>(newtuple);
		toAddIfExecuted = get<6>(newtuple);

		//for each message that is carried out you have to make a function call: t->add(toAddIfExecuted);

	
		if(message == "NothingToBeDone") {
			t->add(toAddIfExecuted);
		}		

		if( message == "exit") {
			exit(0);
		}		
	
		//Print newsgroups
		if(message == "WriteNewsgroups") {
			parser.sendByte(conn, Protocol::COM_LIST_NG);
			parser.sendByte(conn, Protocol::COM_END);
			parser.read(conn, ss);
			int header;
			ss >> header;
			if (header == Protocol::ANS_LIST_NG) {
				int nbrOfNewsGroups;
				ss >> nbrOfNewsGroups; 				
				for(int i = 0; i < nbrOfNewsGroups; i++){
					unsigned int nGId, tiLength;
					string ti;
					ss >> nGId;
					ss >> tiLength;
					ss >> ti;
					while(ti.size() < tiLength){
						string temp;
						ss >> temp;
						ti += " " + temp;
					}
					cout<<nGId<<". "<<ti<<endl;
				}
			} else {
				cout<<"Error reading newsgroups";
			}
			t->add(toAddIfExecuted);
		}

		//Print articles in newsGroup with id = newsGroupId
		if(message == "WriteArticles") {
			parser.sendByte(conn, Protocol::COM_LIST_ART);
			parser.sendIntParameter(conn, newsGroupId);
			parser.sendByte(conn, Protocol::COM_END);
			parser.read(conn, ss);
			int header;
			ss >> header;
			if (header == Protocol::ANS_LIST_ART) {
				int response;
				ss >> response;
				if (response == Protocol::ANS_ACK) {
					int nbrOfArticles;
					ss >> nbrOfArticles;
					for(int i = 0; i < nbrOfArticles; i++){
						unsigned int aId, tiLength;
						string ti;
						ss >> aId;
						ss >> tiLength;
						ss >> ti;
						while(ti.size() < tiLength){
							string temp;
							ss >> temp;
							ti += " " + temp;
						}
						cout<<aId<<". "<<ti<<endl;
					} 
				} else {
					ss >> response;
					cout<<"Newsgroup does not exist"<<endl;
				}
			} else {
				cout<<"Error reading articles"<<endl;
			}
			t->add(toAddIfExecuted);
		}
	
		//Read an article in newsGroup with id = newsGroupId and article with id = articleId
		if(message == "readArticle") {
			parser.sendByte(conn, Protocol::COM_GET_ART);
			parser.sendIntParameter(conn, newsGroupId);
			parser.sendIntParameter(conn, articleId);
			parser.sendByte(conn, Protocol::COM_END);
			parser.read(conn, ss);
			int header;
			ss >> header;
			if (header == Protocol::ANS_GET_ART) {
				int response;
				ss >> response;
				if (response == Protocol::ANS_ACK) {
					unsigned int tiLength, aLength, teLength;					
					string ti, a, te;
					ss >> tiLength;
					ss >> ti;
					while(ti.size() < tiLength){
						string temp;
						ss >> temp;
						ti += " " + temp;
					}
					cout<<"Title: "<<ti<<endl;

					ss >> aLength;
					ss >> a;
					while(a.size() < aLength){
						string temp;
						ss >> temp;
						a += " " + temp;
					}
					cout<<"Author: "<<a<<endl;

					ss >> teLength;
					ss >> te;
					while(te.size() < teLength){
						string temp;
						ss >> temp;
						te += " " + temp;
					}
					cout<<te<<endl;


				} else {
					ss >> response;
					if (response == Protocol::ERR_NG_DOES_NOT_EXIST) {
						cout<<"Newsgroup does not exist"<<endl;
					} else {
						cout<<"Article does not exist"<<endl;
					}
				}
			} else {
				cout<<"Error reading article"<<endl;
			}
			t->add(toAddIfExecuted);

	
		}

		//Delete an newsGroup with id = newsGroupId
		if(message == "deleteNewsgroup") {
			parser.sendByte(conn, Protocol::COM_DELETE_NG);
			parser.sendIntParameter(conn, newsGroupId);
			parser.sendByte(conn, Protocol::COM_END);
			parser.read(conn, ss);
			int header;
			ss >> header;
			if (header == Protocol::ANS_DELETE_NG) {
				int response;
				ss >> response; 				
				if (response == Protocol::ANS_ACK) {
					cout<<"Newsgroup deleted"<<endl;
				} else {
					ss >> response;
					cout<<"Newsgroup could not be deleted"<<endl;
				}
			} else {
				cout<<"Error deleting newsgroup"<<endl;
			}
			t->add(toAddIfExecuted);
		}

		
		//Delete an article in newsGroup with id = newsGroupId and article with id = articleId
		if(message == "deleteArticle") {
			parser.sendByte(conn, Protocol::COM_DELETE_ART);
			parser.sendIntParameter(conn, newsGroupId);
			parser.sendIntParameter(conn, articleId);
			parser.sendByte(conn, Protocol::COM_END);
			parser.read(conn, ss);
			int header;
			ss >> header;
			if (header == Protocol::ANS_DELETE_ART) {
				int response;
				ss >> response; 				
				if (response == Protocol::ANS_ACK) {
					cout<<"Article deleted"<<endl;
				} else {
					ss >> response;
					if (response == Protocol::ERR_NG_DOES_NOT_EXIST) {
						cout<<"Newsgroup does not exist"<<endl;
					} else {
						cout<<"Article does not exist"<<endl;
					}
				}
			} else {
				cout<<"Error deleting article"<<endl;
			}
			t->add(toAddIfExecuted);
													
		}
		
		
		//Create a newsGroup
		if(message == "createNewsgroup") {
			parser.sendByte(conn, Protocol::COM_CREATE_NG);
			parser.sendStringParameter(conn, name);
			parser.sendByte(conn, Protocol::COM_END);
			parser.read(conn, ss);
			int header;
			ss >> header;
			if (header == Protocol::ANS_CREATE_NG) {
				int response;
				ss >> response; 				
				if (response == Protocol::ANS_ACK) {
					cout<<"Newsgroup created"<<endl;
				} else {
					ss >> response;
					cout<<"Newsgroup could not be created"<<endl;
				}
			} else {
				cout<<"Error reading newsgroups"<<endl;
			}
			t->add(toAddIfExecuted);
							
		}

		
		//Create an article in newsGroup with id = newsGroupId
		if(message == "createArticle") {
			parser.sendByte(conn, Protocol::COM_CREATE_ART);
			parser.sendIntParameter(conn, newsGroupId);
			parser.sendStringParameter(conn, name);
			parser.sendStringParameter(conn, author);
			parser.sendStringParameter(conn, text);
			parser.sendByte(conn, Protocol::COM_END);
			parser.read(conn, ss);
			int header;
			ss >> header;
			if (header == Protocol::ANS_CREATE_ART) {
				int response;
				ss >> response; 				
				if (response == Protocol::ANS_ACK) {
					cout<<"Article created"<<endl;
				} else {
					ss >> response;
					cout<<"Article could not be created"<<endl;
				}
			} else {
				cout<<"Error reading newsgroups"<<endl;
			}
			t->add(toAddIfExecuted);
		}
	
	}
	
}

int main(int argc, char* argv[]) {
	if (argc != 3) {
		cerr << "Usage: myclient host-name port-number" << endl;
		exit(1);
	}

	Connection conn(argv[1], atoi(argv[2]));
	if (! conn.isConnected()) {
		cerr << "Connection attempt failed" << endl;
		exit(1);
	}

	run(&conn);

}

	
	
